package com.sun.hui_location;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/** HuiLocationPlugin */
public class HuiLocationPlugin implements FlutterPlugin, ActivityAware,MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private LocationPermission locationPermission;
  private Context mContext;
  private LocationManager locationManager;
  private final static String PROVIDER = LocationManager.GPS_PROVIDER;
  private StreamEventLocaton streamEventLocaton;
  private BinaryMessenger binaryMessenger;
  boolean isGetLocation = false;
  boolean isUsed = true;//标记方法是否被使用 result.success()，只能被使用一次
  float signalCont = 0;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    binaryMessenger = flutterPluginBinding.getBinaryMessenger();
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "hui_location");
    channel.setMethodCallHandler(this);
    mContext = flutterPluginBinding.getApplicationContext();
    locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
  }

  //这里用于MethodChannel的调用
  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) {
    if (call.method.equals("getPlatformVersion")) {
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    }else if(call.method.equals("getLocationData")){

      //Log.e("进来", "onMethodCall: " );
      if (!locationPermission.checkPermissions(Manifest.permission.ACCESS_FINE_LOCATION)) {
        locationPermission.requestPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
        return;
      }

      if (!locationPermission.checkPermissions(Manifest.permission.ACCESS_COARSE_LOCATION)) {
        locationPermission.requestPermissions(Manifest.permission.ACCESS_COARSE_LOCATION);
        return;
      }
/*
      GpsStatus.Listener statusListener = new GpsStatus.Listener() {
        @Override
        public void onGpsStatusChanged(int event) {
          switch (event) {
            //卫星状态改变
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
              //获取当前状态
              @SuppressLint("MissingPermission") GpsStatus gpsStatus = locationManager.getGpsStatus(null);
              //获取卫星颗数的默认最大值
              int maxSatellites = gpsStatus.getMaxSatellites();

              //获取所有的卫星
              Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
              //卫星颗数统计
              int count = 0;
              signalCont = 0;//每监听一次对之前的信号清0
              while (iters.hasNext() && count <= maxSatellites) {
                count++;
                GpsSatellite s = iters.next();
                //卫星的信噪比
                float snr = s.getSnr();
                signalCont = signalCont + snr;
              }
              Log.e("TAGstatus", "onGpsStatusChanged: "+signalCont);
              break;
            default:
              break;
          }

        }
      };
      locationManager.addGpsStatusListener(statusListener);*/

      LocationListener listener = new LocationListener() {
        private static final String TAG = "HuiLocationPlugin";
        @Override
        public void onLocationChanged(Location location) {
          isGetLocation = true;
          if (isUsed){
            isUsed = false;
            //Log.e("进来11", "onMethodCall: " );
            if (location != null ) {
              //Log.e("222", "onLocationChanged: "+location.getLatitude());
              Map<String, Double> locationValue = generateResult(location);
              result.success(locationValue);
              //result.success(location.getLatitude());

            }
          }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
          Log.e("TAG3", "onProviderDisabled: "+provider);
        }

        @Override
        public void onProviderEnabled(String provider) {
          Log.e("TAG2", "onProviderDisabled: "+provider);
        }

        @Override
        public void onProviderDisabled(String provider) {
          Log.e("TAG1", "onProviderDisabled: "+provider);
        }
      };

      locationManager.requestLocationUpdates(PROVIDER,
              1000, 5, listener, mContext.getMainLooper());
    /*   if (!isGetLocation){
        if (isUsed){
          isUsed = false;
          result.success(null);
        }
      }*/

    }else if(call.method.equals("geocoderName")){
      //地理位置解析
      List<Double> args =  call.arguments();
      //Log.e("TAG_zhizhi", "onMethodCall: "+args);

      double lon = args.get(0);
      double lat = args.get(1);
      Geocoder geocoder = new Geocoder(mContext, Locale.CHINA);
      try {
        List<Address> addressList = geocoder.getFromLocation(lat,lon,1);
        Address address = addressList.get(0);
        Map<String, String> locationValue = geocoderResult(address);
        result.success(locationValue);
      } catch (IOException e) {
        e.printStackTrace();
      }

    } else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

  private Map<String, Double> generateResult(Location location) {
    HashMap<String, Double> loc = new HashMap<>();
    loc.put("latitude", location.getLatitude());
    loc.put("longitude", location.getLongitude());
    loc.put("accuracy", (double) location.getAccuracy());
    loc.put("altitude", location.getAltitude());
    loc.put("speed", (double) location.getSpeed());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      loc.put("speed_accuracy", (double) location.getSpeedAccuracyMetersPerSecond());
    }
    loc.put("heading", (double) location.getBearing());
    return loc;
  }

  private Map<String, String> geocoderResult(Address address) {
    HashMap<String, String> addr = new HashMap<>();
    addr.put("addressLines", address.getAddressLine(0));
    addr.put("feature", address.getFeatureName());//街道
    addr.put("admin", address.getAdminArea());//所在省份
    addr.put("locality", address.getLocality());//市
    addr.put("subLocality",address.getSubLocality());//区
    addr.put("thoroughfare",address.getThoroughfare());//所在道路
    return addr;
  }

  //activity 对象引用
  @Override
  public void onAttachedToActivity(@NonNull @org.jetbrains.annotations.NotNull ActivityPluginBinding binding) {
    locationPermission = new LocationPermission(binding.getActivity());
    //用于EventChannel调用
    streamEventLocaton = new StreamEventLocaton(binding.getActivity(),binaryMessenger
            ,locationManager,PROVIDER);
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {

  }

  @Override
  public void onReattachedToActivityForConfigChanges(@NonNull @org.jetbrains.annotations.NotNull ActivityPluginBinding binding) {

  }

  @Override
  public void onDetachedFromActivity() {

  }
}
